package com.desidea.common
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.utils.Dictionary;
	
	import mx.controls.Alert;
	
	public class AppXMLLoader extends EventDispatcher
	{

		private static const LOCAL_CONFIG_FILE:String 				= "SFAS/config/App.xml";
		private static const LOCAL_AUTOUPDATE_CONFIG_FILE:String	= "SFAS/autoupdate/updateconfig.xml";
//		private static const GLOBAL_CONFIG_FILE:String 				= "xml/config.xml";
//		private static const GLOBAL_APPLICATION_FILE:String 		= "xml/Application.xml";

		public static const PRE_LOGIN_XML_LOAD_EVENT	:String = "preLoginXmlLoadedEvent";
		public static const POST_LOGIN_XML_LOAD_EVENT	:String = "postLoginXmlLoadedEvent";
		
		[Event(name="preLoginXmlLoadedEvent", 	type="flash.events.Event")]
		[Event(name="postLoginXmlLoadedEvent", 	type="flash.events.Event")]

		private static var _instance:AppXMLLoader;
		
		private var _xmlDictionary		:Dictionary;

		private var _preLoginXmlCount			:int;
		private var _preLoginXmlLoadedCount		:int;

		private var _postLoginXmlCount			:int;
		private var _postLoginXmlLoadedCount	:int;
		
		private var _isPreLoginXmlLoaded		:Boolean;
		private var _isPostLoginXmlLoaded		:Boolean;
		
		public function AppXMLLoader(broker:SingletonBlocker):void
		{
			_preLoginXmlCount 		= 0;
			_preLoginXmlLoadedCount = 0;

			_postLoginXmlCount = 0;
			_postLoginXmlLoadedCount = 0;

			_isPreLoginXmlLoaded = false;
			_isPostLoginXmlLoaded = false;
			
			_xmlDictionary = new Dictionary();
		}
		
		public static function getInstance():AppXMLLoader{
			if(_instance == null){
				_instance = new AppXMLLoader(new SingletonBlocker());
			}
			return _instance;
		}

		/****************************************************************************************************
		 * PUBLIC METHODS
		 * **************************************************************************************************/
		public function LoadLocalXML():XML{
			var xmlContent:XML = null;
			
			try{
				if(!File.applicationDirectory.resolvePath(LOCAL_CONFIG_FILE).exists){
					Alert.show("Unable to load the Configuration File. Reinstall the application");
					return null;
				}

				var xmlFile:File = File.documentsDirectory.resolvePath(LOCAL_CONFIG_FILE);
				
				if(!xmlFile.exists){ // FIRST TIME RUN
					xmlFile = File.applicationDirectory.resolvePath(LOCAL_CONFIG_FILE);
					xmlFile.copyTo( File.documentsDirectory.resolvePath(LOCAL_CONFIG_FILE));
				}
				
				xmlFile = File.documentsDirectory.resolvePath(LOCAL_CONFIG_FILE);
				var fs:FileStream = new FileStream();
				fs.open(xmlFile, FileMode.READ);
				xmlContent = XML(fs.readUTFBytes(fs.bytesAvailable));
				fs.close();
			}catch(er:Error){
				throw er;
			}
			return xmlContent;
		}

		public function SaveLocalXML(key:String, value:String):XML{
			var xmlContent:XML = null;
			
			try{
				xmlContent = LoadLocalXML();
				
				var lst:XMLList = xmlContent.elements(key);
				lst[0] = value;
				
				var xmlFile:File = File.documentsDirectory.resolvePath(LOCAL_CONFIG_FILE);
				if(xmlFile.exists){
					var newXMLStr:String = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlContent.toXMLString();
					var fs:FileStream = new FileStream();
					fs.open(xmlFile, FileMode.WRITE);
					fs.writeUTFBytes(newXMLStr);
					fs.close();
				}

			}catch(er:Error){
				throw er;
			}
			return xmlContent;
		}

		public function getAutoUpdateConfigFile():File{
			var updateFile:File = null;
			
			try{
				if(!File.applicationDirectory.resolvePath(LOCAL_AUTOUPDATE_CONFIG_FILE).exists){
					Alert.show("Unable to load the AutoUpdate File. Reinstall the application");
					return null;
				}

				updateFile = File.documentsDirectory.resolvePath(LOCAL_AUTOUPDATE_CONFIG_FILE);
				
				if(!updateFile.exists){ // FIRST TIME RUN
					updateFile = File.applicationDirectory.resolvePath(LOCAL_AUTOUPDATE_CONFIG_FILE);
					updateFile.copyTo( File.documentsDirectory.resolvePath(LOCAL_AUTOUPDATE_CONFIG_FILE));
					
					updateFile = File.documentsDirectory.resolvePath(LOCAL_AUTOUPDATE_CONFIG_FILE);
					
					saveAutoUpdateConfigFile(updateFile,"url",CommonClass.ServiceURL+"/autoupdate/update.xml");
					saveAutoUpdateConfigFile(updateFile,"xmlns","http://ns.adobe.com/air/framework/update/configuration/1.0","attribute" );
				}
				
				updateFile = File.documentsDirectory.resolvePath(LOCAL_AUTOUPDATE_CONFIG_FILE);
			}catch(er:Error){
				throw er;
			}
			
			return updateFile;				
		}
		
		private function saveAutoUpdateConfigFile(updateFile:File, key:String, value:String, nodeType:String = "element"):void{

			try{
				var fs:FileStream = new FileStream();
				fs.open(updateFile, FileMode.READ);
				var xmlContent:XML = XML(fs.readUTFBytes(fs.bytesAvailable));
				fs.close();
				
				switch(nodeType){
					case "attribute":
						xmlContent.attribute(key)[0] = value;
						break;
					case "element":
						xmlContent.elements(key)[0] = value;
						break;
					default:
						return;
				}

				var newXMLStr:String = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + xmlContent.toXMLString();
				fs = new FileStream();
				fs.open(updateFile, FileMode.WRITE);
				fs.writeUTFBytes(newXMLStr);
				fs.close();

			}catch(er:Error){
				throw er;
			}
		}

		public function LoadPreLoginXMLs():void{
			_preLoginXmlCount 		= 0;
			_preLoginXmlLoadedCount = 0;
			_isPreLoginXmlLoaded = false;
			
//			LoadPreLoginXML("global.config",GLOBAL_CONFIG_FILE);
//			LoadPreLoginXML("global.app",GLOBAL_APPLICATION_FILE);
			
		}
		
		public function LoadPostLoginXMLs():void{
			_postLoginXmlCount = 0;
			_postLoginXmlLoadedCount = 0;
			_isPostLoginXmlLoaded = false;
			
			var appXml:XML = XML(this.ApplicationXML);
			var postLoginXmlFiles:XMLList = appXml.postloginxml.file as XMLList;
			
			for each(var file:XML in postLoginXmlFiles){
				LoadPostLoginXML(file.@key,file.@value);
			}
		}

		/****************************************************************************************************
		 * PUBLIC PROPERTIES
		 * **************************************************************************************************/
		// Application XML Object
		public function get ApplicationXML():XML{
			if(!_isPreLoginXmlLoaded)
				throw new Error("Pre Login XML is not loaded yet. Make sure to register the event 'preLoginXmlLoadedEvent'");
			return getXMLContent("global.app");
		}

		// Config XML Object
		public function get ConfigXML():XML{
			if(!_isPreLoginXmlLoaded)
				throw new Error("Pre Login XML is not loaded yet. Make sure to register the event 'preLoginXmlLoadedEvent'");
			return getXMLContent("global.config");
		}

		// Generic : XML Object
		public function getXMLByMenuCode(menuCode:String):XML{
			if(!_isPostLoginXmlLoaded)
				throw new Error("PostLogin XML is not loaded yet. Make sure to register the event 'postLoginXmlLoadedEvent'");
			return getXMLContent(menuCode);
		}
		
		/****************************************************************************************************
		 * PRIVATE METHODS
		 * **************************************************************************************************/
		private function LoadPreLoginXML(identifier:String, fileName:String):void{
			_preLoginXmlCount++;
			LoadWebService(identifier, fileName,"pre");
		}

		private function LoadPostLoginXML(identifier:String, fileName:String):void{
			_postLoginXmlCount++;
			LoadWebService(identifier, fileName,"post");
		}
		
		private function LoadWebService(identifier:String, fileName:String, mode:String):void{
			try{
				var xmlContent:XML;
//				var ws:XMLLoaderService = new XMLLoaderService();
//				ws.addgetFileContentEventListener( function(event:GetFileContentResultEvent):void{
//														xmlContent = XML(event.result);
//														_xmlDictionary[identifier] = xmlContent;
//														if(mode == "pre"){
//															raisePreLoginLoadEvent();
//														} 
//														if(mode == "post") {
//															raisePostLoginLoadEvent();
//														}
//													});
//				ws.getFileContent(fileName);
			}catch(err:Error){
				Alert.show(err.toString());
			}
		}
		
		private function raisePreLoginLoadEvent():void{
			_preLoginXmlLoadedCount++;
			if(_preLoginXmlCount>0 && _preLoginXmlLoadedCount == _preLoginXmlCount){
				_isPreLoginXmlLoaded = true;
				dispatchEvent( new Event(PRE_LOGIN_XML_LOAD_EVENT) );
			}
		}

		private function raisePostLoginLoadEvent():void{
			_postLoginXmlLoadedCount++;
			if(_postLoginXmlCount>0 && _postLoginXmlLoadedCount == _postLoginXmlCount){
				_isPostLoginXmlLoaded = true;
				dispatchEvent(new Event(POST_LOGIN_XML_LOAD_EVENT));
			}
		}
		
		private function getXMLContent(identifier:String):XML{
			if(_xmlDictionary[identifier] == null || _xmlDictionary[identifier].toString() == "")
				return null;
			else
				return XML(_xmlDictionary[identifier]);
		}
	}
}

internal class SingletonBlocker {}